/******************************************************************************
/
/  Authors:
/           Ilan   Bar Magen 
/    		Shalev Mintz      066078189  shalevmi@t2  
/
/  Submition date: 9/7/2008
/
/  This file contains:
/
/
******************************************************************************/

#include "stadium.h"

using namespace std;



StatusType Stadium::newFan(int id, int stand, int chair, int team)
{	
	if( (id < 1)                         ||
		((stand < 0) || (stand >= S )) ||
		(chair < 0)                      ||
		((team != 0) && (team != 1)) )
		return FAILURE;

	SL_RESULT  res;
	Fan **fan_ptr;  


	if ( (fan_ptr = FansByID.Data_By_Key(id)) != NULL)
	{
		if ((*fan_ptr)->GetIsBanned() == 1) {return BANNED;}
		else {return FAILURE;}
	}

	if((fan_ptr = Stands[stand].Data_By_Key(chair)) != NULL)
		return FAILURE; // chair is taken

	Fan *newf;
	newf = new Fan(id, stand, chair, team);

	if( ((res = FansByID.Insert_Node(id, newf))   != SL_SUCCESS) ||
		((res = Stands[stand].Insert_Node(chair, newf))!= SL_SUCCESS) ) 
		return convert_result(res);

	Stands[stand].IncTeam(team);

	return SUCCESS;
}





StatusType Stadium::banFan(int stand, int chair)
{
	if(	((stand < 0) || (stand > S - 1)) ||
		(chair < 0) )
		return FAILURE;

	SL_RESULT res;
	Fan **fan_ptr;

	if((fan_ptr = Stands[stand].Data_By_Key(chair)) == NULL)
		return FAILURE; // chair is empty

	(*fan_ptr)->SetIsBanned(true);

	Stands[stand].DecTeam((*fan_ptr)->GetTeam());

	if((res = Stands[stand].Remove_Node(chair)) != SL_SUCCESS)
		return convert_result(res); // failed to remove 

	return SUCCESS;
}


StatusType Stadium::getChair(int id, int * stand, int * chair)
{
	if((id < 1) || (stand == NULL) || (chair == NULL)) return FAILURE;

	Fan **fan_ptr;

	if((fan_ptr = FansByID.Data_By_Key(id)) == NULL )
		return FAILURE; // fan not in stadium

	if ((*fan_ptr)->GetIsBanned() == 1) return FAILURE;

	*stand = (*fan_ptr)->GetStand();
	*chair = (*fan_ptr)->GetChair();

	return SUCCESS;
}


StatusType Stadium::getNumMaccabiFans(int stand, int * numFans)
{
	if((stand < 0) || (stand > S - 1) || (numFans == NULL)) 
		return FAILURE;

	*numFans = Stands[stand].getMaccabiFans();

	return SUCCESS;
}



StatusType Stadium::getNumHapoelFans(int stand, int * numFans)
{
	if((stand < 0) || (stand > S - 1) || (numFans == NULL)) 
		return FAILURE;

	*numFans = Stands[stand].getHapoelFans();

	return SUCCESS;
}

StatusType Stadium::getNumFreeChairs(int stand, int chair, int * freeChairs)
{
	if((stand < 0) || (stand > S - 1) || (chair < 0) || (freeChairs == NULL))
		return FAILURE;
	if(chair == 0)
	{
		*freeChairs = 0;
		return SUCCESS;
	}
	int prev_k = 0, index = 0;
	bool already_exists = false;

	if(Stands[stand].Insert_Node(chair, NULL) == SL_EXISTS)
		already_exists = true;

	index = Stands[stand].Index_By_Key(chair);
	if (index!=0) {
		prev_k = Stands[stand].Key_By_Index(index-1);
		*freeChairs = chair - prev_k - 1; 
	}
	else {
		*freeChairs = chair;
	}

	if(!already_exists) Stands[stand].Remove_Node(chair);

	return SUCCESS;
}


StatusType Stadium::separateStands(int stand1, int stand2)
{
	return SUCCESS;
}

SL_RESULT Release_data(Fan** dat) {  //only when storing a pointer in the data field of skip nodes.
	delete *dat;
	return SL_SUCCESS;

}


